package com.soft.line.filter;

import com.google.gson.Gson;
import org.apache.catalina.filters.RemoteIpFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.Charset;


/**
 * @author wu.xueqiao on 2020/5/12.
 * @version 0.1
 */
@Configuration
public class ConfigurationFilter {
    @Bean
    public HttpMessageConverter<String> responseBodyConverter() {
        StringHttpMessageConverter converter = new StringHttpMessageConverter(
                Charset.forName("UTF-8"));
        return converter;
    }

    @Bean
    public RemoteIpFilter remoteIpFilter() {
        return new RemoteIpFilter();
    }

    @Bean
    public FilterRegistrationBean testFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new MyFilter());
        registration.addUrlPatterns("/*");
        registration.addInitParameter("name", "value");
        registration.setName("MyFilter");
        registration.setOrder(1);
        return registration;
    }

    public class MyFilter implements Filter {
        @Override
        public void destroy() {
        }

        @Override
        public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
                             final FilterChain chain)
                throws IOException, ServletException {

            final Gson gson = new Gson();
            //final ResultData rd = new ResultData();
            final ResponseWrapper responseWrapper=new ResponseWrapper();
            final HttpServletRequest request = (HttpServletRequest) servletRequest;
            final HttpServletResponse response = (HttpServletResponse) servletResponse;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,OPTIONS,DELETE");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "Origin,X-Requested-With,Content-Type,Accept,Access-Token,token");
            final String uri = request.getRequestURI();
            String auth = request.getHeader("Access-Token");
            Token token = null;
            if (!uri.contains("/")) {
            //if (!uri.contains("/login")&&!uri.contains("/autoLogin") && !uri.contains("/bindUserInfo") && !uri.contains("/uploadContractAttach") && !uri.contains("/uploadCertificateAttach") && !uri.contains("/uploadFiles") ) {
                if (auth == null || "".equals(auth)) {
                    if (uri.contains("/file/download/")) {
                        auth = request.getParameter("token");
                        if (auth == null || "".equals(auth)) {
                            response.setContentType("application/json");
                            response.setCharacterEncoding("UTF-8");
                            //rd.setMsg("Authentication Failed: Require Authorization");
                            responseWrapper.failure(StatusCode.SC_10000.val(),"Authentication Failed: Require Authorization");
                            //rd.setStatus("10000");
                            final String write = gson.toJson(responseWrapper);
                            response.getWriter().write(write);
                            return;
                        }
                    } else {
                        response.setContentType("application/json");
                        response.setCharacterEncoding("UTF-8");
                        //rd.setMsg("Authentication Failed: Require Authorization");
                        responseWrapper.failure(StatusCode.SC_10000.val(),"Authentication Failed: Require Authorization");
                        //rd.setStatus("10000");
                        final String write = gson.toJson(responseWrapper);
                        response.getWriter().write(write);
                        return;
                    }
                }
                token = new Token(auth);
                if (token.getErr() == Token.ExpiredJwtError) {
                    response.setContentType("application/json");
                    response.setCharacterEncoding("UTF-8");
                    //rd.setMsg("Authentication Failed: 认证过期");
                    responseWrapper.failure(StatusCode.SC_10001.val(),"Authentication Failed: 认证过期");
                    // rd.setStatus("10000");
                    final String write = gson.toJson(responseWrapper);
                    response.getWriter().write(write);
                    return;
                }
                if (token.getErr() == Token.SignatureError) {
                    response.setContentType("application/json");
                    response.setCharacterEncoding("UTF-8");
                    //rd.setMsg("Authentication Failed: 非法认证");
                    responseWrapper.failure(StatusCode.SC_10002.val(),"Authentication Failed: 非法认证");

                    //rd.setStatus("10000");
                    final String write = gson.toJson(responseWrapper);
                    response.getWriter().write(write);
                    return;
                }
                if (HttpRequestUtil.REDIS_SERVICE.getKeyValue(token.getUsername()) == null
                        || "".equals(HttpRequestUtil.REDIS_SERVICE.getKeyValue(token.getUsername()))) {
                    response.setContentType("application/json");
                    response.setCharacterEncoding("UTF-8");
                    //rd.setMsg("会话过期，请重新登录");
                    responseWrapper.failure(StatusCode.SC_10003.val(),"会话过期，请重新登录");
                    //rd.setStatus("10000");
                    final String write = gson.toJson(responseWrapper);
                    response.getWriter().write(write);
                    return;
                }
                HttpRequestUtil.REDIS_SERVICE.setKeyTimeout(token.getUsername(), HttpRequestUtil.expire);
            }
            try {
                chain.doFilter(request, response);
            } catch (final Exception e) {
                System.out.println(e.toString());
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                //rd.setMsg("服务器异常");
                responseWrapper.failure(StatusCode.SC_500.val(),"请求失败");
                //rd.setStatus("10001");
                final String write = gson.toJson(responseWrapper);
                response.getWriter().write(write);
                return;
            }
        }

        @Override
        public void init(FilterConfig arg0) throws ServletException {
        }
    }
}